/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.projeto.persistence.jpa;

/**
 *
 * @author matheus
 */
import java.util.ResourceBundle;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtility {

        private static final String FILE_BASE = "project";
        private static final String USED_PU = "pu";
        private static EntityManagerFactory entityManagerFactory;
        private static EntityManager entityManager;
        private static ResourceBundle resourceBundle;
        private static String persistence;

        /**
         * Le o arquivo de propriedades
         */
        static {
                resourceBundle = ResourceBundle.getBundle(FILE_BASE);
                persistence = resourceBundle.getString(USED_PU);
        }

        /**
         * Metodo que cria um EntityManager.
         */
        public void createEntityManager() {
                if (entityManagerFactory == null || !entityManagerFactory.isOpen()) {
                        entityManagerFactory = Persistence.createEntityManagerFactory(persistence);
                }
                entityManager = entityManagerFactory.createEntityManager();
        }

        /**
         * Metodo que recupera o EntityManager de uma determinada classe.
         * @return O EntityManager.
         */
        @SuppressWarnings("unchecked")
        public EntityManager getEntityManager() {
                if (entityManager != null && entityManager.isOpen()) {
                        shutdown(entityManager);
                }
                createEntityManager();
                return entityManager;
        }

        /**
         * Metodo que inicializa uma transacao num determinado EntityManager.
         * @param em O EntityManager no qual a transacao sera iniciada.
         */
        public void beginTransaction(EntityManager em) {
                if (em != null && em.isOpen()) {
                        em.getTransaction().begin();
                }
        }

        /**
         * Shutdown no Entity Manager e na Factory.
         * @param em Entity Manager.
         */
        private void shutdown(EntityManager em) {
                if (entityManager != null && entityManager.isOpen()) {
//                                entityManager.close();
                        entityManager = null;
                }
        }

        /**
         * Shutdown no Entity Manager e na Factory.
         * @param em Entity Manager.
         */
        private void shutdownAndCloseFactory(EntityManager em) {
                if (em == entityManager) {
                        if (entityManager != null && entityManager.isOpen()) {
                                entityManager.close();
                        }
                        if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
                                entityManagerFactory.close();
                        }
                }
        }

        /**
         * Metodo que finaliza uma transacao.
         * @param em O EntityManager no qual a transacao sera finalizada.
         * @param clazz
         */
        public void commitTransaction(EntityManager em) {
                if (em != null && em.isOpen()) {
                        em.getTransaction().commit();
                }
                shutdown(em);
        }

        /**
         * Metodo que finaliza uma transacao.
         * @param em O EntityManager no qual a transacao sera finalizada.
         */
        public void commitTransactionAndCloseFactory(EntityManager em) {
                if (em != null && em.isOpen()) {
                        em.getTransaction().commit();
                }
                shutdownAndCloseFactory(em);
        }

        /**
         * Metodo que cancela uma transacao.
         * @param em O EntityManager no qual a transacao sera cancelada.
         */
        public void rollbackTransaction(EntityManager em) {
                if (em != null && em.isOpen()) {
                        if (em.getTransaction().isActive()) {
                                em.getTransaction().rollback();
                        }
                        shutdown(em);
                }
        }
}

